home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / audio / DAT / verifydat.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.3 KB  |  352 lines

  1. /*
  2.  * A simple program to verify that a DAT tape
  3.  * has been correctly written.
  4.  *
  5.  * Doug Cook
  6.  * Silicon Graphics, Inc., December 1993
  7.  *
  8.  * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
  9.  * ALL RIGHTS RESERVED
  10.  * Permission to use, copy, modify, and distribute this software for
  11.  * any purpose and without fee is hereby granted, provided that the above
  12.  * copyright notice appear in all copies and that both the copyright notice
  13.  * and this permission notice appear in supporting documentation, and that
  14.  * the name of Silicon Graphics, Inc. not be used in advertising
  15.  * or publicity pertaining to distribution of the software without specific,
  16.  * written prior permission.
  17.  *
  18.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  19.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  20.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  21.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  22.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  23.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  24.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  25.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  26.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  27.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  28.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  29.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  30.  *
  31.  * US Government Users Restricted Rights
  32.  * Use, duplication, or disclosure by the Government is subject to
  33.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  34.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  35.  * clause at DFARS 252.227-7013 and/or in similar or successor
  36.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  37.  * Unpublished-- rights reserved under the copyright laws of the
  38.  * United States.  Contractor/manufacturer is Silicon Graphics,
  39.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  40.  *
  41.  */
  42.  
  43. #include <sys/types.h>
  44. #include <sys/errno.h>
  45. #include <sys/tpsc.h>
  46. #include <sys/mtio.h>
  47. #include <sys/prctl.h>
  48. #include <fcntl.h>
  49. #include <dataudio.h>
  50. #include <stdio.h>
  51. #include <audio.h>
  52.  
  53. int dat;            /* dat tape fd */
  54. static char *datdev = "/dev/nrtape";
  55. int testpat = 0;
  56. int printtc = 0;
  57. int derrcnt = 0, terrcnt = 0;
  58.  
  59. int 
  60. get_firmware_revision(int fd, int *maj, int *min)
  61. {
  62.     ct_g0inq_data_t info;
  63.     char revbuf1[MAX_INQ_PRL + 1];
  64.  
  65.     if (ioctl(fd, MTSCSIINQ, &info) >= 0) {
  66.         strncpy(revbuf1, (char *)info.id_prl, MAX_INQ_PRL);
  67.         *maj = atoi(strtok(revbuf1, "."));
  68.         *min = atoi(strtok(NULL, "."));
  69.         return 0;
  70.     }
  71.     else {
  72.         return -1;     /*ioctl failed */
  73.     }
  74. }
  75.  
  76. static DTFRAME dtf;
  77. static int program, index;
  78.  
  79. int
  80. rewind_dat(int fd)
  81. {
  82.     int i;
  83.     struct mtop mtc;
  84.     struct mtaudio mta;
  85.     struct mtget mtg;
  86.  
  87.     /*
  88.      * Get some information about the DAT media
  89.      * We'll use this momentarily.
  90.      */
  91.     if (ioctl(fd, MTIOCGET, &mtg) < 0) {
  92.         perror("Couldn't issue MTIOCGET");
  93.         return(0);
  94.     }
  95.  
  96.     /*
  97.      * rewind the tape.
  98.      * Note that a rewind does not block. The rewind goes on while
  99.      * the program continues. The first write will block until
  100.      * the rewind completes. 
  101.      * We want the drive in audio mode here because BOT is different
  102.      * between data and audio modes (data mode rewinds to logical
  103.      * BOT, which is a little ways into the tape, and we want real
  104.      * BOT). 
  105.      */
  106.     if ((mtg.mt_erreg & (CT_AUD_MED >> 16)) == 0) {
  107.     printf("tape is not an audio tape\n");
  108.         return 0;
  109.     }
  110.     mtc.mt_op = MTREW;
  111.     mtc.mt_count = 1;
  112.     if (ioctl(fd, MTIOCTOP, &mtc) < 0) {
  113.         perror("MTREW failed");
  114.     return 0;
  115.     }
  116.     return 1;
  117. }
  118.  
  119. int
  120. prepare_dat(int fd)
  121. {
  122.     struct mtop mtc;
  123.     struct dttimecode *tcp;
  124.     struct dttimepack *tpp;
  125.     struct dttimepack *tpp1;
  126.  
  127.     /*
  128.      * Put the DAT drive in audio mode. 
  129.      */
  130.     mtc.mt_op = MTAUD;
  131.     mtc.mt_count = 1;
  132.     if (ioctl(fd, MTIOCTOP, &mtc) < 0) {
  133.         if (oserror() != EAGAIN) {
  134.             perror("Couldn't put DAT into audio mode");
  135.             return(0);
  136.         }
  137.     }
  138.     return 1;
  139. }
  140.  
  141. int
  142. verify_dat(int fd)
  143. {
  144.     DTFRAME frame;
  145.     struct dttimepack *tpp;
  146.     struct dttimecode *tcp;
  147.     struct dttimecode exp_ptime;
  148.     struct dttimecode exp_atime;
  149.     char *s1 = "--:--:--:--";
  150.     char *s2 = "--:--:--:--";
  151.     int program = -1;
  152.     int printed = 0;
  153.     int li = 0;                /* are we in lead-in area? */
  154.     int x=1;
  155.     int firsta = 1, firstp = 1;
  156.     int i1,i2,index = 0;
  157.     int j,np,atime_ok;
  158.     unsigned long y;
  159.     unsigned long *p;
  160.  
  161.     while(x) {
  162.     if ((x = read(fd,&frame,sizeof(DTFRAME))) < 0) {
  163.         perror("read failed");
  164.         return 0;
  165.     }
  166.  
  167.         /*
  168.          * get the program number from the frame
  169.          */
  170.         if (frame.subcode.sid.pno3 != 0xa
  171.             && frame.subcode.sid.pno3 != 0xb
  172.             && frame.subcode.sid.pno3 != 0xe) {
  173.             np = DTpnotodec(frame.subcode.sid.pno1,
  174.                 frame.subcode.sid.pno2, frame.subcode.sid.pno3);
  175.         if (np != program) {
  176.             printf("\nprogram %d   \n",np);
  177.             bzero(&exp_ptime,sizeof(struct dttimecode));
  178.         program = np;
  179.         }
  180.         li = 0;
  181.         }
  182.     else {
  183.         if (!li && frame.subcode.sid.pno3 == 0xb) {
  184.         li = 1;
  185.         printf("lead-in...\n");
  186.         }
  187.         if (frame.subcode.sid.pno3 == 0xe) {
  188.         printf("\nlead-out...\n");
  189.         return 1;
  190.         }
  191.         continue;
  192.     }
  193.         tpp = (struct dttimepack *)&frame.subcode.packs[DTP_PTIME-1];
  194.     tcp = &(tpp->tc);
  195.     if ((i1 = DTbcdtodec(tpp->index.dhi,tpp->index.dlo)) < 100) {
  196.         if (i1 != index) {
  197.             index = i1;
  198.             printf("\nindex %d   \n",i1);
  199.         }
  200.     }
  201.         if (DTtcvalid(tcp)) {
  202.         if (!firstp && bcmp(tcp,&exp_ptime,sizeof(struct dttimecode))) {
  203.         DTtimetoa(s1,&exp_ptime);
  204.         DTtimetoa(s2,tcp);
  205.             printf("unexpected ptime: wanted %s got %s\n",s1,s2);
  206.         terrcnt++;
  207.         exp_ptime = *tcp;
  208.         }
  209.         else if (firstp) {
  210.         DTtimetoa(s2,tcp);
  211.             printf("Initial ptime: %s\n",s2);
  212.         exp_ptime = *tcp;
  213.         firstp = 0;  /* first valid p-time resets 'firstp' */
  214.         }
  215.         }
  216.     else {
  217.         printf("invalid ptime\n");
  218.     }
  219.         tpp = (struct dttimepack *)&frame.subcode.packs[DTP_ATIME-1];
  220.     tcp = &(tpp->tc);
  221.     if ((i2 = DTbcdtodec(tpp->index.dhi,tpp->index.dlo)) < 100) {
  222.         index = i2; 
  223.     }
  224.     atime_ok = 0;
  225.         if (DTtcvalid(tcp)) {
  226.         atime_ok = 1;
  227.         if (!firsta && bcmp(tcp,&exp_atime,sizeof(struct dttimecode))) {
  228.         DTtimetoa(s1,&exp_atime);
  229.         DTtimetoa(s2,tcp);
  230.             printf("unexpected atime: wanted %s got %s\n",s1,s2);
  231.         terrcnt++;
  232.         exp_atime = *tcp;
  233.         }
  234.         else if (firsta) {
  235.         DTtimetoa(s2,tcp);
  236.             printf("Initial atime: %s\n",s2);
  237.         exp_atime = *tcp;
  238.         firsta = 0;  /* first valid a-time resets 'firsta' */
  239.         }
  240.         }
  241.     else {
  242.         printf("invalid atime (ignoring test-pattern in this frame)\n");
  243.     }
  244.     DTtimetoa(s1,tcp);
  245.     if (printtc) printf("%s",s1);
  246. /*
  247.     printf("%s\n",s1);
  248. */
  249.     fflush(stdout);
  250.     if (i1 != i2) {
  251.         printf("index numbers mismatch between atime and ptime\n");
  252.         terrcnt++;
  253.     }
  254.     DTinctime(&exp_atime);
  255.     if (index != 0) {
  256.         /* index 0 ptime should stay at 0 */
  257.         DTinctime(&exp_ptime);
  258.     }
  259.     if (testpat && index != 0 && atime_ok) {
  260.         /*
  261.          * attempt to match test-pattern on tape
  262.          */
  263.             tpp = (struct dttimepack *)&frame.subcode.packs[DTP_ATIME-1];
  264.             tcp = &tpp->tc;
  265.             y = (tcp->hhi << 28) | (tcp->hlo << 24)
  266.               | (tcp->mhi << 20) | (tcp->mlo << 16)
  267.               | (tcp->shi << 12) | (tcp->slo << 8)
  268.               | (tcp->fhi << 4) | tcp->flo;
  269.             p = (unsigned long *) &frame.audio;
  270.             for (j = 0; j < DTDA_DATASIZE; j += sizeof(long)) {
  271.                 if (*p != y) {
  272.              if (!printed) {
  273.             DTtimetoa(s1,tcp);
  274.                 printf("data error (atime %s): got 0x%x at pos %d, wanted 0x%x\n",
  275.                 s1,*p, j, y);
  276.             printed=1;
  277.             }
  278.             derrcnt++;
  279.         };
  280.         p++;
  281.         y++;
  282.             }
  283.     }
  284.     printed=0;
  285.     }
  286.     return 1;
  287. }
  288.  
  289. main(int argc, char **argv)
  290. {
  291.     int status;
  292.     int n = 1;
  293.     int i;
  294.     int excl_id;            /* id as returned by mediad */
  295.     int maj, min;            /* dat firmware rel major&minor # */
  296.     extern char *optarg;
  297.     extern int optind;
  298.     int c;
  299.  
  300.     while ((c = getopt(argc, argv, "tp")) != EOF) 
  301.     switch (c) {
  302.         case 't' :
  303.         printf("Checking test-patterns...\n");
  304.             testpat=1;
  305.         break;
  306.         case 'p' :
  307.         printtc=1;
  308.         break;
  309.         case '?' :
  310.             fprintf(stderr, "usage: %s [-tp]\n",argv[0]);
  311.         exit(-1);
  312.     }
  313.     
  314.     /*
  315.      * Ask mediad for exclusive access to the DAT drive.
  316.      */
  317.     excl_id = mediad_get_exclusiveuse(datdev, argv[0]);
  318.  
  319.     /*
  320.      * Open the DAT drive
  321.      */
  322.     dat = open(datdev, O_RDONLY);
  323.     if (dat < 0) {
  324.         perror("Could not open DAT drive:");
  325.         exit(-1);
  326.     }
  327.  
  328.  
  329.     if (get_firmware_revision(dat, &maj, &min) < 0) {
  330.         fprintf(stderr,"Couldn't get DAT firmware revision\n");
  331.         exit(-1);
  332.     }
  333.     /* pre-2.63 DAT drives don't work with audio */
  334.     if (maj < 2 || (maj == 2 && min < 63)) {
  335.         fprintf(stderr,"DAT firmware rev %d.%d is too old -- you must have 2.63 or greater\n",maj,min);
  336.         exit(-1);
  337.     }
  338.  
  339.     if (prepare_dat(dat) < 0) {
  340.     exit(-1);
  341.     }
  342.     if (rewind_dat(dat) < 0) {
  343.     exit(-1);
  344.     }
  345.     if (verify_dat(dat) < 0) {
  346.     exit(-1);
  347.     }
  348.     printf("%d timecode errors, %d data errors\n",terrcnt,derrcnt);
  349.     if (terrcnt > 0) exit (-2);
  350.     if (derrcnt > 0) exit (-3);
  351. }
  352.